#light

namespace Demos.WshScripting

#r @"webtools.core.dll"

open System
open FSharp.WebTools
open Demos.WshScripting

(*-----------------------------------------------------------------------------------------------*)
module Main = 

  // Classes to register
  open FSharp.WebTools.ClientLibrary
  
  let types = [ (type Size);
                (type Position);
                (type Rectangle);
                (type Convert);
                (type EventArgs);
                (type CancelEventArgs);
                (type MouseEventArgs);
                (type Timer);
                (type LibXmlHttpRequest);
                (type JsonSerializer);
                (type JsonDeserializer);

                (type Async);
                (type AsyncMonad);

                (type Demos.WshScripting.Console);

                (type Internal.StringJS);
                (type Internal.Int32);
                (type Internal.Double);    
                (type Internal.MathJS);
                (type Internal.Random);
                (type Internal.Tuple);
                (type Internal.TimeSpan);
                (type Internal.DateTime);
                (type Internal.StringBuilder);
                (type Internal.TextWriter); // this has to be in correct order determined by inheritance
                (type Internal.StringWriter);
                (type Internal.HtmlTextWriter);
                (type Internal.DiscriminatedUnion);    
                (type Internal.ResizeArray<obj>);    
                (type Internal.Stack<obj>);    
                (type Internal.ListModule);    
                (type Internal.PrintModule);    
                (type Internal.ArrayModule);  ]    
    
  // generate JS from F# 
  let generateClassC (t:Type) ctx = 
    let cls = ClientClassQuot.getClassFromClientType t |> ClientClassQuot.checkUnresolved
    Generator.generateClassCode cls ctx

  let generateClass wr (t:Type) = 
    generateClassC t (Generator.createContext wr) |> ignore
    
  let generateClassHierarchy wr (t:Type) =
    let types = ClassQuot.getClientClassHierarchy t 
    let types = if (types = []) then [t] else (List.rev types)    
    let ctx = Generator.createContext wr
    types |> List.fold_left (fun st t -> generateClassC t st) ctx |> ignore
    
  let hierarchTypes = 
    [ (type SampleClass); ] 

  let userCode = @"
      var c = new SampleClass();
      c.ctor(); 
      c.Main(); "
  
  let main() =
    ClientExpressions.mappingProc.RegisterAssembly
      (System.Reflection.Assembly.GetExecutingAssembly())
  
    // Generate JS file
    use wr = new IO.StreamWriter("test.js")
    wr.WriteLine("// ASP.NET \"Atlas\" JavaScript runtime");
    use rd = new IO.StreamReader("corelib.js")
    let mutable s = "";
    while(s <> null) do
      while(s.IndexOf("  ") <> -1) do s <- s.Replace("  ", " ");
      //if (not (s.StartsWith("//"))) then 
      //  let s = if s.Trim() <> "" && not (s.EndsWith(";")) then s + ";" else s
      wr.WriteLine(s);          
      s <- rd.ReadLine();
      
    // F# -> JS
    wr.WriteLine("\n\n// F# -> JS generated code");        
    types |> List.iter (generateClass wr) 
    hierarchTypes |> List.iter (generateClassHierarchy wr) 
      
    // User code..
    wr.WriteLine("\n\n// User code")
    wr.WriteLine(userCode)
      
  main()